/*
 moxl - Modular XML Library
 Copyright (c) 2007, Malcolm Sparks

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package moxl.tokenizer.xml.document;

import java.io.IOException;

import moxl.reader.LocateableReader;
import moxl.tokenizer.CodePage;
import moxl.tokenizer.EndOfFileState;
import moxl.tokenizer.Token;
import moxl.tokenizer.TokenReadyState;
import moxl.tokenizer.AbstractTokenizerState;
import moxl.tokenizer.TokenizerStateMachine;
import moxl.tokenizer.xml.XmlTokenType;

public class DocumentStartState extends AbstractTokenizerState
{

	private static AbstractTokenizerState instance = new DocumentStartState();

	public static AbstractTokenizerState getInstance()
	{
		return instance;
	}

	@Override
	public boolean isStartState()
	{
		return true;
	}

	@Override
	public void accept(TokenizerStateMachine stateMachine, Token token, LocateableReader reader) throws IOException
	{
		int c = reader.read();
		if (c == -1)
		{
			stateMachine.changeState(EndOfFileState.getInstance());

		}
		else if (c == ' ')
		{
			token.append(c);
			stateMachine.changeState(DocumentSpaceOrWhitespaceState.getInstance());

		}
		else if (CodePage.isWhitespace(c))
		{
			token.append(c);
			token.setTokenType(XmlTokenType.WHITESPACE);
			stateMachine.changeState(DocumentInWhiteSpaceState.getInstance());

		}
		else if (c == '<')
		{
			token.append(c);
			stateMachine.changeState(DocumentOpenChevronState.getInstance());

		}
		else if (c == '>')
		{
			token.append(c);
			token.setTokenType(XmlTokenType.CLOSE_CHEVRON);
			stateMachine.changeState(TokenReadyState.getInstance());

		}
		else if (c == '/')
		{
			token.append(c);
			stateMachine.changeState(DocumentSlashState.getInstance());

		}
		else if (c == '?')
		{
			token.append(c);
			stateMachine.changeState(DocumentQuestionMarkState.getInstance());

		}
		else if (c == '!')
		{
			token.append(c);
			token.setTokenType(XmlTokenType.EXCLAMATION_MARK);
			stateMachine.changeState(TokenReadyState.getInstance());

		}
		else if (c == '"')
		{
			token.append(c);
			token.setTokenType(XmlTokenType.DOUBLE_QUOTE);
			stateMachine.changeState(TokenReadyState.getInstance());

		}
		else if (c == '\'')
		{
			token.append(c);
			token.setTokenType(XmlTokenType.SINGLE_QUOTE);
			stateMachine.changeState(TokenReadyState.getInstance());

		}
		else if (c == '=')
		{
			token.append(c);
			token.setTokenType(XmlTokenType.EQUALS);
			stateMachine.changeState(TokenReadyState.getInstance());

		}
		else if (c == '%')
		{
			token.append(c);
			token.setTokenType(XmlTokenType.PERCENT);
			stateMachine.changeState(TokenReadyState.getInstance());

		}
		else if (c == '-')
		{
			token.append(c);
			stateMachine.changeState(DocumentHyphenOrDoubleHyphenState.getInstance());

		}
		else if (c == '[')
		{
			token.append(c);
			token.setTokenType(XmlTokenType.OPEN_BRACKET);
			stateMachine.changeState(TokenReadyState.getInstance());

		}
		else if (c == ']')
		{
			token.append(c);
			stateMachine.changeState(CloseBracketOrCloseSectionState.getInstance());
		}

		else if (CodePage.isLetter(c) || c == '_' || c == ':')
		{
			token.append(c);
			token.setTokenType(XmlTokenType.NAME);
			stateMachine.changeState(DocumentInNameState.getInstance());

		}
		else
		{
			token.append(c);
			token.setTokenType(XmlTokenType.ILLEGAL_CHARACTER);
			stateMachine.changeState(TokenReadyState.getInstance());
		}
	}

}
